/**
 * @file adaptive_crop.cpp
 * @brief 智能裁剪模块实现
 * 
 * 实现基于内容分析的动态裁剪算法。
 * 融合灰度方差和边缘跳变次数两种指标。
 */
#include "adaptive_crop.h"
//#include <cmath>
//#include <algorithm>
//#include <vector>
//#include <fstream>
//#include <sstream>

/**
 * @brief 计算单行灰度方差
 * @param row 输入行数据
 * @param width 行宽度
 * @return 方差值


 static float calcRowVariance(const unsigned char* row, int width) {
    // 使用单精度 Welford 算法以提高数值稳定性
    // 并在移植到 TC264/AURIX 时利用单精度 FPU 加速。
    if (width <= 1) return 0.0f;
    float mean = 0.0f;
    float M2 = 0.0f;
    int n = 0;
    for (int j = 0; j < width; j++) {
        n++;
        float x = static_cast<float>(row[j]);
        float delta = x - mean;
        mean += delta / static_cast<float>(n);
        M2 += delta * (x - mean);
    }
    // population variance
    float var = M2 / static_cast<float>(n);
    // clamp tiny negative values caused by rounding
    if (var < 0.0f && var > -1e-6f) var = 0.0f;
    return var;
}
*/




/**
 * @brief 计算单行边缘跳变次数
 * @param row 输入行数据
 * @param width 行宽度
 * @return 返回该行的跳变次数（使用行均值作为自适应阈值）
 */
static int countEdgeTransitions(const unsigned char* row, int width) 
{
    // 使用行均值作为自适应阈值以提高对光照变化的鲁棒性。
    // 先计算该行的均值，然后根据均值判断像素高低来统计跳变次数。
    long sum = 0;
    for (int j = 0; j < width; j++) sum += row[j];
    int mean = static_cast<int>(sum / width);

    int count = 0;
    bool prev = row[0] > mean;

    for (int j = 1; j < width; j++) {
        bool curr = row[j] > mean;
        if (curr != prev) {
            count++;
        }
        prev = curr;
    }
    return count;
}

void adaptiveCrop(const unsigned char fullImage[IMAGE_HEIGHT][IMAGE_WIDTH], int& top, int& bottom) 
{
    // MCU友好型智能裁剪逻辑：
    // 1. 前部（0-150行）：分析trans，连续5点小于Q3（第3四分位数）即判定结束裁剪
    // 2. 后部（350-480行）：分析trans，连续5点大于Q3即判定为下降段起点
    // 3. 区域硬性上限
    // 4. 所有数据均用C数组，unsigned char/int，避免STL
    const int H = IMAGE_HEIGHT;
    const int W = IMAGE_WIDTH;
    const int FRONT_END = 150; // 前部分析范围
    const int BACK_START = 350; // 后部分析起点
    const int BACK_END = IMAGE_HEIGHT;   // 后部分析终点
    const int WIN = 5; // 连续点窗口
    const int MIN_HEIGHT = 100; // 最小保留高度

    // 1. 计算每行trans（unsigned char）
    unsigned char trans[H];
    // float var[H]; // 注释掉var相关，保留但不参与运算
    for (int i = 0; i < H; i++) {
        trans[i] = (unsigned char)countEdgeTransitions(fullImage[i], W);
        // var[i] = calcRowVariance(fullImage[i], W); // 注释掉
    }

    // --- 前部Q3 ---
    // 计数排序优化 - 嵌入式友好，无递归，确定性内存
    int count[256] = {0};
    
    // 统计频次
    for (int i = 0; i < FRONT_END; i++) {
        count[trans[i]]++;
    }
    
    // 找Q3（第3四分位数）
    int target = FRONT_END * 3 / 4;  // 第113个元素（0索引为112）
    int sum = 0;
    unsigned char q3_front = 255;  // 安全默认值
    
    for (int i = 0; i < 256; i++) {
        sum += count[i];
        if (sum >= target) {
            q3_front = i;
            break;
        }
    }

    // --- 后部Q3 ---
    // 计数排序优化 - 嵌入式友好，无递归，确定性内存
    int count_back[256] = {0};
    
    // 统计频次
    for (int i = BACK_START; i < BACK_END; i++) {
        count_back[trans[i]]++;
    }
    
    // 找Q3（第3四分位数）
    int target_back = (BACK_END - BACK_START) * 3 / 4;
    int sum_back = 0;
    unsigned char q3_back = 255;  // 安全默认值
    
    for (int i = 0; i < 256; i++) {
        sum_back += count_back[i];
        if (sum_back >= target_back) {
            q3_back = i;
            break;
        }
    }

    // --- 前部裁剪 ---
    int front_crop = 0;
    for (int i = 0; i <= FRONT_END - WIN; i++) {
        bool all_low = true;
        for (int k = 0; k < WIN; k++) {
            if (trans[i + k] >= q3_front) {
                 all_low = false; 
                 break;
            }
        }
        if (all_low) { 
            front_crop = i + WIN - 1; 
            break; 
        }
    }

    // --- 后部裁剪 ---
    int back_crop = H - 1;
    for (int i = BACK_START; i <= BACK_END - WIN; i++) {
        bool all_high = true;
        for (int k = 0; k < WIN; k++) {
            if (trans[i + k] <= q3_back) {
                all_high = false; 
                break;
            }
        }
        if (all_high) { 
            back_crop = i + WIN - 1; 
            break; 
        }
    }

    // --- 输出最终裁剪区域 ---
   /* if (back_crop - front_crop + 1 < MIN_HEIGHT) {
        int mid = (front_crop + back_crop) / 2;
        front_crop = mid - MIN_HEIGHT / 2; 
        if (front_crop < 0) {
            front_crop = 0;
        }
        back_crop = front_crop + MIN_HEIGHT - 1; 
        if (back_crop >= H) {
            back_crop = H - 1;
        }
    }*/
    top = front_crop;
    bottom = back_crop + 1; // [top, bottom)

}